home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 22 / CU Amiga Magazine's Super CD-ROM 22 (1998)(EMAP Images)(GB)[!][issue 1998-05].iso / PowerPC / Programming / PPCSmallEiffel / lib_se / effective_arg_list.e < prev    next >
Encoding:
Text File  |  1998-01-16  |  11.5 KB  |  578 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class EFFECTIVE_ARG_LIST
  17. --
  18. -- For an effective arguments list (for a routine call). 
  19. -- 
  20.    
  21. inherit 
  22.    GLOBALS
  23.       redefine fill_tagged_out_memory 
  24.       end;
  25.    
  26. creation make
  27.    
  28. feature {EFFECTIVE_ARG_LIST}   
  29.    
  30.    list: ARRAY[EXPRESSION];
  31.      -- Corresponding list of actual arguments.
  32.  
  33. feature 
  34.    
  35.    current_type: TYPE;
  36.      -- Not Void when checked in.
  37.    
  38. feature 
  39.    
  40.    make(l: like list) is
  41.       require
  42.      l.lower = 1;
  43.      not l.empty;
  44.       do
  45.      list := l;
  46.       ensure
  47.      list = l
  48.       end;
  49.    
  50. feature
  51.  
  52.    fill_tagged_out_memory is
  53.       local
  54.      p: POSITION;
  55.      ct: TYPE;
  56.      rtm: STRING;
  57.       do
  58.      p := start_position;
  59.      if p /= Void then
  60.         p.fill_tagged_out_memory;
  61.      end;
  62.      ct := current_type;
  63.      if ct /= Void then
  64.         rtm := ct.run_time_mark;
  65.         if rtm /= Void then
  66.            tagged_out_memory.append(" ct=");
  67.            tagged_out_memory.append(rtm);
  68.         end;
  69.      end;
  70.       end;
  71.  
  72.    run_class: RUN_CLASS is
  73.       do
  74.      Result := current_type.run_class;
  75.       end;
  76.    
  77.    start_position: POSITION is
  78.       do
  79.      Result := list.item(1).start_position;
  80.       end;
  81.    
  82.    count: INTEGER is
  83.       do
  84.      Result := list.upper;
  85.       end;
  86.    
  87.    expression(i: INTEGER): EXPRESSION is
  88.       require
  89.      1 <= i;
  90.      i <= count;
  91.       do
  92.      Result := list.item(i);
  93.       ensure
  94.      Result /= Void
  95.       end;
  96.    
  97.    first: EXPRESSION is
  98.       do
  99.      Result := list.first;
  100.       end;
  101.    
  102.    match_with(rf: RUN_FEATURE) is
  103.      -- Check the good match for real/formal arguments.
  104.       require
  105.      rf /= Void;
  106.       local
  107.      fal: FORMAL_ARG_LIST;
  108.      i: INTEGER;
  109.      e: EXPRESSION;
  110.      at, ft: TYPE;
  111.       do
  112.      fal := rf.arguments;
  113.      if fal = Void then
  114.         eh.add_position(rf.start_position);
  115.         error(start_position,em2);
  116.      end;
  117.      if nb_errors = 0 and then fal.count /= count then
  118.         eh.add_position(fal.start_position);
  119.         error(start_position,em2);
  120.      end;
  121.      from  
  122.         i := list.upper;
  123.      until
  124.         i = 0 or else nb_errors > 0
  125.      loop
  126.         e := list.item(i);
  127.         at := e.result_type;
  128.         ft := fal.type(i);
  129.         check
  130.            at.is_run_type;
  131.            ft.is_run_type;
  132.         end;
  133.         if e.is_void then
  134.            if ft.is_expanded then
  135.           eh.add_position(e.start_position);
  136.           error(ft.start_position,
  137.             "Cannot pass Void for expanded argument.");
  138.            end;
  139.         elseif ft.is_like_current then
  140.            if e.is_current then
  141.            elseif at.run_type.is_a(ft.run_type) then
  142.           if at.run_type.is_expanded then
  143.           elseif ft.run_type.is_a(at.run_type) then
  144.           else
  145.              eh.add_position(e.start_position);
  146.              error(ft.start_position,em1);
  147.           end;
  148.            else
  149.           eh.add_position(e.start_position);
  150.           error(ft.start_position,em1);
  151.            end;
  152.         elseif ft.is_like_feature then
  153.            if at.run_type.is_a(ft.run_type) then
  154.            else
  155.           eh.add_position(e.start_position);
  156.           error(ft.start_position," It is not Like <feature>.");
  157.            end;
  158.         elseif is_like_argument(e,at,ft) then
  159.         elseif at.run_type.is_a(ft.run_type) then
  160.         else
  161.            eh.print_as_error;
  162.            eh.add_position(ft.start_position);
  163.            error(e.start_position,"Real/Formal argument mismatch (3).");
  164.         end;
  165.         -- For automatic conversion Expanded <-> Reference :
  166.         at := at.run_type;
  167.         ft := ft.run_type;
  168.         if ft.is_expanded then
  169.            if at.is_expanded then
  170.           -- Expanded into Expanded.
  171.            else
  172.           -- Reference into Expanded.
  173.           ft.used_as_reference;
  174.            end;
  175.         elseif at.is_expanded then
  176.            -- Expanded into Reference.
  177.            at.used_as_reference;
  178.         else
  179.            -- Reference into Reference.
  180.         end;
  181.         i := i - 1;
  182.      end;
  183.       end;
  184.    
  185.    to_runnable(ct: TYPE): like Current is
  186.       require
  187.      ct.run_type = ct
  188.       local
  189.      i: INTEGER;
  190.      e1, e2: EXPRESSION;
  191.       do
  192.      if current_type = Void then
  193.         current_type := ct;
  194.         from  
  195.            i := list.upper;
  196.         until
  197.            i = 0
  198.         loop
  199.            e1 := list.item(i);
  200.            e2 := e1.to_runnable(current_type);
  201.            if e2 = Void then
  202.           error(e1.start_position,"Bad expression.");
  203.            elseif e1 /= e2 then
  204.           list.put(e2,i);
  205.            end;
  206.            i := i - 1;
  207.         end;
  208.         if nb_errors = 0 then
  209.            Result := Current;
  210.         end;
  211.      elseif ct.run_class = run_class then -- *** C'est POSSIBLE ???? ****
  212.         Result := Current;
  213.      else
  214.         !!Result.make(list.twin);
  215.         Result := Result.to_runnable(ct);
  216.      end;
  217.       end;
  218.    
  219.    afd_check is
  220.       require
  221.      current_type /= Void
  222.       local
  223.      i: INTEGER;
  224.       do
  225.      from  
  226.         i := list.upper;
  227.      until
  228.         i = 0
  229.      loop
  230.         list.item(i).afd_check;
  231.         i := i - 1;
  232.      end;
  233.       end;
  234.  
  235.    compile_to_c(fal: FORMAL_ARG_LIST) is
  236.      -- Produce C code for all expressions of the list.
  237.       require
  238.      cpp.on_c;
  239.      count = fal.count
  240.       local
  241.      i, up: INTEGER;
  242.       do
  243.      from  
  244.         i := 1;
  245.         up := count;
  246.      until
  247.         i > up
  248.      loop
  249.         compile_to_c_ith(fal,i);
  250.         i := i + 1;
  251.         if i <= up then
  252.            cpp.put_character(',');
  253.         end;
  254.      end;
  255.       ensure
  256.      cpp.on_c
  257.       end;
  258.    
  259.    compile_to_c_ith(fal: FORMAL_ARG_LIST; index: INTEGER) is
  260.      -- Produce C code for expression `index'.
  261.       require
  262.      cpp.on_c;
  263.      count = fal.count;
  264.      1 <= index;
  265.      index <= count
  266.       local
  267.      e: EXPRESSION;
  268.      ft: TYPE;
  269.       do
  270.      e := expression(index);
  271.      ft := fal.type(index).run_type;
  272.      e.mapping_c_arg(ft);
  273.       ensure
  274.      cpp.on_c
  275.       end;
  276.  
  277.    compile_to_c_old is 
  278.       local
  279.      i: INTEGER;
  280.       do 
  281.      if list /= Void then
  282.         from  
  283.            i := 1;
  284.         until
  285.            i > list.upper
  286.         loop
  287.            list.item(i).compile_to_c_old;
  288.            i := i + 1;
  289.         end;        
  290.      end;
  291.       end;
  292.  
  293.    compile_to_jvm_old is 
  294.       local
  295.      i: INTEGER;
  296.       do 
  297.      if list /= Void then
  298.         from  
  299.            i := 1;
  300.         until
  301.            i > list.upper
  302.         loop
  303.            list.item(i).compile_to_jvm_old;
  304.            i := i + 1;
  305.         end;        
  306.      end;
  307.       end;
  308.  
  309.    compile_to_jvm(fal: FORMAL_ARG_LIST): INTEGER is
  310.       require
  311.      count = fal.count
  312.       local
  313.      i, up: INTEGER;
  314.       do
  315.      from  
  316.         i := 1;
  317.         up := count;
  318.      until
  319.         i > up
  320.      loop
  321.         Result := Result + compile_to_jvm_ith(fal,i);
  322.         i := i + 1;
  323.      end;
  324.       end;
  325.    
  326.    compile_to_jvm_ith(fal: FORMAL_ARG_LIST; index: INTEGER): INTEGER is
  327.       require
  328.      count = fal.count;
  329.      1 <= index;
  330.      index <= count
  331.       local
  332.      e: EXPRESSION;
  333.      ft: TYPE;
  334.       do
  335.      e := expression(index);
  336.      ft := fal.type(index).run_type;
  337.      Result :=  e.compile_to_jvm_into(ft);
  338.       end;
  339.  
  340.    use_current: BOOLEAN is
  341.       local
  342.      i: INTEGER;
  343.       do
  344.      from  
  345.         i := 1
  346.      until
  347.         i > count or else Result
  348.      loop
  349.         Result := expression(i).use_current;
  350.         i := i + 1;
  351.      end;
  352.       end;
  353.  
  354.    is_pre_computable: BOOLEAN is
  355.       local
  356.      i: INTEGER;
  357.       do
  358.      from
  359.         i := count;
  360.         Result := true;
  361.      until
  362.         not Result or else i = 0
  363.      loop
  364.         Result := expression(i).is_pre_computable;
  365.         i := i - 1;
  366.      end;
  367.       end;
  368.      
  369.    pretty_print is
  370.       local
  371.      i: INTEGER;
  372.       do
  373.      fmt.put_character('(');
  374.      from  
  375.         i := 1;
  376.      until
  377.         i > count
  378.      loop
  379.         expression(i).pretty_print;
  380.         i := i + 1;
  381.         if i <= count then
  382.            fmt.put_character(',');
  383.         end;
  384.      end;
  385.      fmt.put_character(')');
  386.       end;
  387.  
  388.    short is
  389.       local
  390.      i: INTEGER;
  391.       do
  392.      short_print.hook_or("op_eal","(");
  393.      from  
  394.         i := 1;
  395.      until
  396.         i > count
  397.      loop
  398.         expression(i).short;
  399.         i := i + 1;
  400.         if i <= count then
  401.            short_print.hook_or("eal_sep",",");
  402.         end;
  403.      end;
  404.      short_print.hook_or("cl_eal",")");
  405.       end;
  406.  
  407.    is_static: BOOLEAN is
  408.      -- Is true when only `is_static' expression are used.
  409.       local
  410.      i: INTEGER;
  411.       do
  412.      from
  413.         Result := true;
  414.         i := list.upper;
  415.      until
  416.         not Result or else i = 0
  417.      loop
  418.         Result := expression(i).is_static;
  419.         i := i - 1;
  420.      end;
  421.       end;
  422.  
  423.    can_be_dropped: BOOLEAN is
  424.      -- Is true when only `can_be_dropped' expression are used.
  425.       local
  426.      i: INTEGER;
  427.       do
  428.      from
  429.         Result := true;
  430.         i := list.upper;
  431.      until
  432.         not Result or else i = 0
  433.      loop
  434.         Result := expression(i).can_be_dropped;
  435.         i := i - 1;
  436.      end;
  437.       end;
  438.       
  439. feature {RUN_FEATURE_3,RUN_FEATURE_4}
  440.  
  441.    isa_dca_inline(relay_rf, rf: RUN_FEATURE): BOOLEAN is
  442.      -- Assume `rf' is inside `relay_rf'.
  443.       require
  444.      relay_rf /= Void;
  445.      rf /= Void
  446.       local
  447.      relay_args, args: FORMAL_ARG_LIST;
  448.      e: EXPRESSION;
  449.      i, r: INTEGER;
  450.       do
  451.      relay_args := relay_rf.arguments;
  452.      args := rf.arguments;
  453.      from 
  454.         Result := true;
  455.         i := list.upper;
  456.         isa_dca_inline_memory.force(false,i);
  457.         isa_dca_inline_memory.clear_all;
  458.      until
  459.         not Result or else i = 0
  460.      loop
  461.         e := list.item(i);
  462.         r := e.isa_dca_inline_argument;
  463.         inspect
  464.            r
  465.         when 0 then
  466.            Result := false;
  467.         when -1 then
  468.            if args.type(i).is_expanded then
  469.           Result := e.result_type.is_expanded;
  470.            else
  471.           Result := e.result_type.is_reference;
  472.            end;
  473.         else
  474.            check
  475.           r > 0
  476.            end;
  477.            isa_dca_inline_memory.put(true,r);
  478.            if relay_args.type(r).is_reference then
  479.           if args.type(i).is_reference then
  480.              Result := e.result_type.is_reference;
  481.           else
  482.              Result := false;
  483.           end;
  484.            elseif args.type(i).is_expanded then
  485.           Result := e.result_type.is_expanded;
  486.            else
  487.           Result := false;
  488.            end;
  489.         end;
  490.         i := i - 1;
  491.      end;
  492.      if Result then
  493.         -- No arguments are lost :
  494.         from
  495.            i := relay_rf.arg_count;
  496.         until
  497.            not Result or else i = 0
  498.         loop
  499.            Result := isa_dca_inline_memory.item(i);
  500.            i := i - 1;
  501.         end;
  502.      end;
  503.       end;
  504.  
  505. feature {NONE}
  506.    
  507.    isa_dca_inline_memory: ARRAY[BOOLEAN] is
  508.       once
  509.      !!Result.make(1,2);
  510.       end;
  511.    
  512. feature {C_PRETTY_PRINTER}
  513.  
  514.    dca_inline(fal: FORMAL_ARG_LIST) is
  515.       require
  516.      fal /= Void
  517.       local
  518.      i, up: INTEGER;
  519.       do
  520.      from
  521.         up := list.upper;
  522.         i := 1;
  523.      until
  524.         i > up
  525.      loop
  526.         dca_inline_ith(fal,i);
  527.         i := i + 1;
  528.         if i <= up then
  529.            cpp.put_character(',');
  530.         end;
  531.      end;
  532.       end;
  533.  
  534.    dca_inline_ith(fal: FORMAL_ARG_LIST; index: INTEGER) is
  535.       require
  536.      fal /= Void;
  537.      index <= count
  538.       local
  539.      e: EXPRESSION;
  540.      ft: TYPE;
  541.       do
  542.      e := expression(index);
  543.      ft := fal.type(index).run_type;
  544.      e.dca_inline_argument(ft);
  545.       end;
  546.  
  547. feature {NONE}
  548.  
  549.    is_like_argument(e: EXPRESSION; at, ft: TYPE): BOOLEAN is
  550.       local
  551.      tla: TYPE_LIKE_ARGUMENT;
  552.      ot: TYPE;
  553.       do
  554.      tla ?= ft;
  555.      if tla /= Void then
  556.         Result := true;
  557.         ot := expression(tla.rank).result_type;
  558.         if not at.run_type.is_a(ot.run_type) then
  559.            eh.add_position(e.start_position);
  560.            error(ft.start_position," It is not Like <argument>.");
  561.         end;
  562.      end;
  563.       end;
  564.  
  565. feature {NONE}
  566.    
  567.    em1: STRING is " It is not Like Current.";
  568.    em2: STRING is "Bad number of arguments.";
  569.    
  570. invariant
  571.    
  572.    count > 0;
  573.    
  574.    list.lower = 1
  575.    
  576. end -- EFFECTIVE_ARG_LIST
  577.  
  578.